﻿<meta charset="utf-8">

<style>
.noborder{border:groove;background-color:#999;width:300px;}
.divWithCanvas{background-color:#fff;width:100%;height:240px;}
</style>

<div class="noborder"><p>
<div class="divWithCanvas" id="containerView"><canvas id="webglView" style="width:100%;height:100%"></canvas></div><br>

<input type="button" value = "run triangle" title="绘制三角形" onclick="renderTriangle()">
<input type="button" value = "run rectangle" title="绘制矩形" onclick="renderRectangle()">
<input type="button" value = "run circle" title="绘制圆形" onclick="renderCircle()">

</p></div>

<script type="text/javascript">
var webgl = null;
function webglInit() {
    var myCanvasObject = document.getElementById("webglView"); //此处的webglView为你的canvas的id
	var myDivObject = document.getElementById("containerView"); //此处的containerView为你的canvas的父div元素id
    webgl = myCanvasObject.getContext("experimental-webgl");
	if(webgl == null)
		alert("你的浏览器不支持webgl");
	myCanvasObject.width = myDivObject.clientWidth; //千万注意，参见下面说明。
	myCanvasObject.height = myDivObject.clientHeight; //同上
    webgl.viewport(0, 0, myDivObject.clientWidth, myDivObject.clientHeight);//同上
}
</script>

<script type="text/javascript">
var vertexShaderObject = null;
var fragmentShaderObject = null;

function shaderInitWithVertexAndFragmentShader(vsh, fsh) {
	vertexShaderObject = webgl.createShader(webgl.VERTEX_SHADER);
    fragmentShaderObject = webgl.createShader(webgl.FRAGMENT_SHADER);
    webgl.shaderSource(vertexShaderObject, vsh);
    webgl.shaderSource(fragmentShaderObject, fsh);
    webgl.compileShader(vertexShaderObject);
    webgl.compileShader(fragmentShaderObject);
	if (!webgl.getShaderParameter(vertexShaderObject, webgl.COMPILE_STATUS)) { alert(webgl.getShaderInfoLog(vertexShaderObject) + "in vertex shader"); return; }
    if (!webgl.getShaderParameter(fragmentShaderObject, webgl.COMPILE_STATUS)) { alert(webgl.getShaderInfoLog(fragmentShaderObject) + "in fragment shader"); return; }
}
</script>

<script type="text/javascript">
var programObject;
var v4PositionIndex;
function initShaderProgram(positionName) {
    programObject = webgl.createProgram();
    webgl.attachShader(programObject, vertexShaderObject);
    webgl.attachShader(programObject, fragmentShaderObject);
    webgl.bindAttribLocation(programObject, v4PositionIndex, positionName);
    webgl.linkProgram(programObject);
	if (!webgl.getProgramParameter(programObject, webgl.LINK_STATUS)) {
        alert(webgl.getProgramInfoLog(programObject));
        return;
    }
    webgl.useProgram(programObject);
}
</script>

<script type="text/javascript">
function renderWebGL(vertices, vSize, vLen, vsh, fsh, positionName){
    webglInit();
    shaderInitWithVertexAndFragmentShader(vsh, fsh);
    initShaderProgram(positionName);

	var buffer = webgl.createBuffer();
    webgl.bindBuffer(webgl.ARRAY_BUFFER, buffer);
    webgl.bufferData(webgl.ARRAY_BUFFER, new Float32Array(vertices), webgl.STATIC_DRAW);

	webgl.enableVertexAttribArray(v4PositionIndex);
    webgl.vertexAttribPointer(v4PositionIndex, vSize, webgl.FLOAT, false, 0, 0);

    webgl.clearColor(0.0, 0.0, 0.0, 1.0);
    webgl.clear(webgl.COLOR_BUFFER_BIT);
    webgl.drawArrays(webgl.TRIANGLE_STRIP, 0, vLen);
}
</script>

<script type="text/javascript">

//使用上面封装的函数在绘制一个渐变色三角形, 由于前面封装的功劳，我们现在可以绘制很多东西而只需要提供shader文本代码和顶点就行了。
function renderTriangle()
{
	var vertices = 
	[
		0.0, 0.5,
		-0.5, -0.5,
		0.5, -0.5,
	];
	var vsh = 
		"precision mediump float;" + 
		"attribute vec4 position;" +
		"varying vec2 textureCoordinate;" +
		"void main()" +
		"{" +
		"	gl_Position = position;" +
		"	textureCoordinate = position.xy + 0.5;" +
		"}";
	var fsh = 
		"precision mediump float;" +
		"varying vec2 textureCoordinate;" +
		"void main()" +
		"{" +
		"	gl_FragColor = vec4(textureCoordinate, 0.0, 1.0);" +
		"}";
	
	renderWebGL(vertices, 2, 3, vsh, fsh, "position");
}

function renderRectangle()
{
	var vertices = 
	[
		0.5, 0.5,
		0.5, -0.5,
		-0.5, 0.5,
		-0.5, -0.5
	];
	var vsh = 
		"precision mediump float;" + 
		"attribute vec4 position;" +
		"varying vec2 textureCoordinate;" +
		"void main()" +
		"{" +
		"	gl_Position = position;" +
		"	textureCoordinate = position.xy + 0.5;" +
		"}";
	var fsh = 
		"precision mediump float;" +
		"varying vec2 textureCoordinate;" +
		"void main()" +
		"{" +
		"	gl_FragColor = vec4(textureCoordinate, 0.0, 1.0);" +
		"}";
	
	renderWebGL(vertices, 2, 4, vsh, fsh, "position");
}

function renderCircle()
{
	var vertices = 
	[
		1.0, 1.0,
		1.0, -1.0,
		-1.0, 1.0,
		-1.0, -1.0
	];
	var vsh = 
		"precision mediump float;" + 
		"attribute vec4 position;" +
		"varying vec2 textureCoordinate;" +
		"void main()" +
		"{" +
		"	gl_Position = position;" +
		"	textureCoordinate = position.xy;" +
		"}";
	var fsh = 
		"precision mediump float;" +
		"varying vec2 textureCoordinate;" +
		"void main()" +
		"{" +
		"	if(length(textureCoordinate) < 0.5)" +
		"		gl_FragColor = vec4(textureCoordinate + 0.5, 0.0, 1.0);" +
		"	else gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);" +
		"}";	
	renderWebGL(vertices, 2, 4, vsh, fsh, "position");
}

</script>